﻿using Raider.WinForms.Actions.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Raider.WinForms.Actions.Standard
{
    /// <summary>
    /// Base class for all actions in the Edit category.
    /// </summary>
    [HideProperty("Enabled", "AsyncUpdate", "AsyncExecute")]
    public abstract class EditAction : StandardAction
    {
        protected Control lastFocusedControl;

        /// <summary>
        /// Initializes a new instance of the <see cref="EditAction"/>.
        /// </summary>
        /// <param name="title">Default title for the action (empty by default).</param>
        /// <param name="shortcut">Default shortcut for the action (none by default).</param>
        /// <param name="image">Default image for the action (<c>null</c> by default).</param>
        protected EditAction(string title = "", Keys shortcut = Keys.None, Image image = null)
            : base(title, "Edit", shortcut, image)
        {
        }

        /// <summary>
        /// Actions from Edit category do not support asynchronous execution.
        /// </summary>
        /// <exception cref="InvalidOperationException">When trying to set this property to <c>true</c>.</exception>
        [Description("Actions from Edit category do not support asynchronous execution.")]
        public sealed override bool AsyncExecute
        {
            get { return base.AsyncExecute; }
            set
            {
                if (value)
                {
                    throw new InvalidOperationException(GetType() + " does not support asynchronous execution.");
                }

                base.AsyncExecute = value;
            }
        }

        /// <summary>
        /// Actions from Edit category do not support asynchronous update.
        /// </summary>
        /// <exception cref="InvalidOperationException">When trying to set this property to <c>true</c>.</exception>
        [Description("Actions from Edit category do not support asynchronous update.")]        
        public sealed override bool AsyncUpdate
        {
            get { return base.AsyncUpdate; }
            set
            {
                if (value)
                {
                    throw new InvalidOperationException(GetType() + " does not support asynchronous update.");
                }

                base.AsyncUpdate = value;
            }
        }

        protected override void OnExecute(ExecuteEventArgs args)
        {
            base.OnExecute(args);

            // Retrieve focused control again.
            lastFocusedControl = ControlUtils.GetFocusedControl();
        }

        protected override void OnUpdate(UpdateEventArgs args)
        {
            base.OnUpdate(args);

            // If Update is invoked by ActionManager, it passes currently focused control
            // using UpdateEventArgs.Argument property (to improve the perfomance).
            if (UpdateKind == ActionUpdateKind.Automatic && args.Argument is Control)
            {
                lastFocusedControl = (Control)args.Argument;
            }
            else
            {
                lastFocusedControl = ControlUtils.GetFocusedControl();
            }
        }
    }
}
